package utils

import (
	"MoSkeleton/framework/utils"
	"github.com/gin-gonic/gin"
	"github.com/zavitax/sortedset-go"
)

const (
	//默认设定的优先级：user >  default > system
	HandlerChain_Sorted_Default = 20000
	HandlerChain_Sorted_User    = 30000
	HandlerChain_Sorted_System  = 10000

	ChainFlowContinue_False = false
	ChainFlowContinue_True  = true
)

type ChainFlowContinue bool
type ChainFlowFunc func(c *gin.Context) ChainFlowContinue

type HandlerChain struct {
	sset *sortedset.SortedSet[string, int64, ChainFlowFunc]
}

func NewHandlerChain() *HandlerChain {
	sset := sortedset.New[string, int64, ChainFlowFunc]()
	return &HandlerChain{sset: sset}
}

func (h *HandlerChain) Add(flowFunc ChainFlowFunc) string {
	var name = utils.GetFuncFullName(flowFunc)
	return h.AddWithNameAndSort(name, flowFunc, HandlerChain_Sorted_Default)
}

func (h *HandlerChain) AddWithSort(flowFunc ChainFlowFunc, sort int64) string {
	var name = utils.GetFuncFullName(flowFunc)
	return h.AddWithNameAndSort(name, flowFunc, sort)
}

func (h *HandlerChain) AddWithName(name string, flowFunc ChainFlowFunc) string {
	return h.AddWithNameAndSort(name, flowFunc, HandlerChain_Sorted_Default)
}
func (h *HandlerChain) AddWithNameAndSort(name string, flowFunc ChainFlowFunc, sort int64) string {
	h.sset.AddOrUpdate(name, sort, flowFunc)
	return name
}

func (h *HandlerChain) removeByName(name string) {
	h.sset.Remove(name)
}

func (h *HandlerChain) DoChain() gin.HandlerFunc {
	return func(c *gin.Context) {
		h.sset.IterFuncRangeByRank(1, h.sset.GetCount()-1, func(key string, flowFunc ChainFlowFunc) bool {
			if flowFunc(c) == ChainFlowContinue_False {
				return false
			}
			return true
		})
	}
}
